package gui 
{
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import gui.factory.StyleFactory;
	import utils.Logger;
	/**
	 * ...
	 * @author Dmitriy Gaiduk
	 */
	/**
	 *  when value change
	 */
	[Event(name = "change", type = "flash.events.Event")]
	
	public class NumStepper extends Sprite
	{
		private var _valueNum:Number;
		private var _values:Vector.<String> = null;
		private var _min:Number;
		private var _max:Number;
		private var _step:Number;
		private var _titleNumStep:String;
		private var _textFieldNum:TextField;
		private var _downButton:SimpleButton;
		private var _upButton:SimpleButton;
		private var posNumText:PositionInfo;
		private var _stepperWidth:Number;
		private var _stepperHeight:Number;
		private var _index:int;
		private var _textBg:DisplayObject;
		public var titleTF:TextField;
		public var titlePos:PositionInfo;
		private var posDown:PositionInfo;
		private var posUp:PositionInfo;
		private var posBg:PositionInfo;
		/**
		 * User data
		 */
		private var _tag:Object;
		
		private var _groupeName:String;
		
		public function NumStepper(numStepTitle:String = "") 
		{
			_titleNumStep = "";
			initStepper();
			//addEventListener(Event.ADDED_TO_STAGE , handleAddedToStage);
		}
		
		private function handleAddedToStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
			
			initStepper();
		}
		
		private function initStepper():void 
		{
			_min = 0;
			_max = 10;
			_step = 1;
			valueNum = 0;
			
			_stepperWidth = 100;
			_stepperHeight = 50;
			
			if (_downButton == null)
			{
				_downButton = new SimpleButton();
			}
			_downButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
			
			addChild(_downButton);
			
			if (_upButton == null)
			{
				_upButton = new SimpleButton();
			}
			_upButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
			
			addChild(_upButton);
			
			
			posDown = new PositionInfo();
			posDown.align = PositionInfo.ALIGN_LEFT;
			posDown.addAlign(PositionInfo.ALIGN_CENTR_Y);
			posDown.leftPadding = 0;
			posDown.bottomPadding = 0;
			
			posUp = new PositionInfo();
			posUp.align = PositionInfo.ALIGN_RIGHT;
			posUp.addAlign(PositionInfo.ALIGN_CENTR_Y);
			posUp.rightPadding = 0;
			posUp.bottomPadding = 0;
			
			setPosition(_downButton, posDown);
			setPosition(_upButton, posUp);
			
			
			// text
			posBg = new PositionInfo();
			posBg.align = PositionInfo.ALIGN_NONE;
			
			posNumText = new PositionInfo();
			posNumText.align = PositionInfo.ALIGN_CENTR_X;
			_textFieldNum = new TextField();
			addChild(_textFieldNum);
			
			// title
			titleTF = new TextField();
			titleTF.text = _titleNumStep;
			addChild(titleTF);
			titlePos = new PositionInfo();
			titlePos.align = PositionInfo.ALIGN_CENTR_X;
			titlePos.addAlign(PositionInfo.ALIGN_TOP);
			setPosition(titleTF, titlePos);
			
			invalidateNow();
			updateTextNum();
		}
		
		public function invalidateNow():void
		{
			setPosition(_downButton, posDown);
			setPosition(_upButton, posUp);
			if((_textBg != null))
			{
				centrBetweenButtons(_textBg, posBg);
			}
			centrBetweenButtons(_textFieldNum, posNumText);
			setPosition(_textBg, posBg);
			setPosition(titleTF, titlePos);
			//setPosition(_textFieldNum, posNumText);
			//drawRect(this.graphics);
			updateTextNum();
		}
		
		
		private function centrBetweenButtons(obj:DisplayObject, posInfo:PositionInfo):void
		{
			posInfo.posX = (_upButton.x - _downButton.x - _downButton.width - obj.width) * 0.5 + 
								_downButton.x + _downButton.width;
			posInfo.posY = (_upButton.height - obj.height) * 0.5 + _upButton.y;
		}
		// добавляет бэкграунд для числового поля
		public function addTextBG(bg:DisplayObject):void
		{
			if ((_textBg != null) && (_textBg.parent != null))
			{
				_textBg.parent.removeChild(_textBg);
			}
			_textBg = bg;
			addChild(_textBg);
			setPosition(_textBg, posBg);
			
			if ((_textFieldNum != null) && (_textFieldNum.parent != null))
			{
				_textBg.parent.removeChild(_textFieldNum);
				addChild(_textFieldNum);
				setPosition(_textFieldNum, posNumText);
			}
			
		}
		
		private function drawRect(gr:Graphics):void
		{
			gr.clear();
			gr.lineStyle(1, 0x000000);
			gr.drawRect(0, 0, width, height);
		}
		private function setPosition(obj:DisplayObject, pos:PositionInfo):void 
		{
			if ((obj != null) && (pos != null))
			{
				obj.x = pos.getPosX(width, obj.width);
				obj.y = pos.getPosY(height, obj.height);
			}
		}
		
		private function updateTextNum():void
		{
			if (_textFieldNum != null)
			{
				if (_values != null)
				{
					_textFieldNum.text = valueString;
				}else
				{
					_textFieldNum.text = valueNum.toString();
				}
				
				setPosition(_textFieldNum, posNumText);
				//textField.x = textPos.getPosX(width, textField.width);
				//textField.y = textPos.getPosY(width, textField.height);
			}
		}
		
		private function handleButtonClick(e:MouseEvent):void 
		{
			switch(e.currentTarget)
			{
				case _downButton:
						decrease();
					break;
				case _upButton:
						increase();
					break;
			}
		}
		
		private function decrease():void 
		{
			if (_values != null)
			{
				index -= 1;
				//_index--;
				//_index = Math.max(0, _index);
			}else
			{
				valueNum -= _step;
				//_valueNum = Math.max(_min, _valueNum);
			}
		}
		
		private function increase():void 
		{
			if (_values != null)
			{
				index += 1;
				//_index = Math.min((_values.length-1), _index);
			}else
			{
				valueNum += _step;
				//_valueNum = Math.min(_max, _valueNum);
			}
		}
		
		
		public function get step():Number 
		{
			return _step;
		}
		
		public function set step(value:Number):void 
		{
			_step = value;
		}
		
		public function get valueNum():Number 
		{
			/*if (_values != null)
			{
				return _values[_index];
			}else*/
			{
				return _valueNum;
			}
		}
		
		public function get valueString():String 
		{
			if (_values != null)
			{
				return _values[_index];
			}else
			{
				return null;
			}
		}
		
		public function set valueNum(value:Number):void 
		{
			if (value < _min)
			{
				_valueNum = _min;
			}else if (value > _max)
			{
				_valueNum = _max
			}else
			{
				_valueNum = value;
			}
			dispatchEvent(new Event(Event.CHANGE));
			updateTextNum();
		}
		
		public function get values():Vector.<String> 
		{
			return _values;
		}
		
		public function set values(value:Vector.<String>):void 
		{
			_values = value;
			if (_values != null)
			{
				_index = 0;
			}
		}
		
		public function get min():Number 
		{
			return _min;
		}
		
		public function set min(value:Number):void 
		{
			_min = value;
		}
		
		public function get max():Number 
		{
			return _max;
		}
		
		public function set max(value:Number):void 
		{
			_max = value;
		}
		
		public function get index():int 
		{
			return _index;
		}
		
		public function set index(value:int):void 
		{
			if (_values != null)
			{
				if (value < 0)
				{
					_index = 0;
				}else if (value > (_values.length - 1))
				{
					_index = _values.length - 1
				}else
				{
					_index = value;
				}
			}
			dispatchEvent(new Event(Event.CHANGE));
			updateTextNum();
		}
		
		override public function get width():Number 
		{
			return _stepperWidth;
		}
		
		override public function set width(value:Number):void 
		{
			_stepperWidth = value;
		}
		
		override public function get height():Number 
		{
			return _stepperHeight;
		}
		
		override public function set height(value:Number):void 
		{
			_stepperHeight = value;
		}
		
		
		public function get textFieldNum():TextField 
		{
			return _textFieldNum;
		}
		
		public function set textFieldNum(value:TextField):void 
		{
			_textFieldNum = value;
		}
		
		public function get tag():Object 
		{
			return _tag;
		}
		
		public function set tag(value:Object):void 
		{
			_tag = value;
		}
		
		
		
		public function get downButton():SimpleButton 
		{
			return _downButton;
		}
		
		public function set downButton(value:SimpleButton):void 
		{
			if (_downButton != null)
			{
				_downButton.removeEventListener(MouseEvent.CLICK, handleButtonClick);
				if (_downButton.parent != null)
				{
					_downButton.parent.removeChild(_downButton);
				}
			}
			_downButton = value;
			_downButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
			addChild(_downButton);
		}
		
		public function get upButton():SimpleButton 
		{
			return _upButton;
		}
		
		public function set upButton(value:SimpleButton):void 
		{
			if (_upButton != null)
			{
				_upButton.removeEventListener(MouseEvent.CLICK, handleButtonClick);
				if (_upButton.parent != null)
				{
					_upButton.parent.removeChild(_upButton);
				}
			}
			_upButton = value;
			_upButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
			addChild(_upButton);
		}
		
		public function get groupeName():String 
		{
			return _groupeName;
		}
		
		public function set groupeName(value:String):void 
		{
			_groupeName = value;
		}
		
		private function log(msg:String):void
		{
			Logger.log(this, msg);
		}
		
		public function geComponentBounds():Rectangle
		{
			var calcX:Number = _downButton.x;
			var calcY:Number = Math.min(_downButton.y, _upButton.y, _textBg.y);
			var calcH:Number = Math.max(_downButton.y + _downButton.height, 
										_upButton.y + _upButton.height, 
										_textBg.y + _textBg.height) - calcY;
			var calcW:Number = _upButton.x + _upButton.width - calcX;
			
			return new Rectangle(calcX, calcY, calcW, calcH);	
		}
	}

}